package all.com.jinyongqunxiax.model.mod.manager;

import com.randy.fundation.DrawUtils;
import com.randy.fundation.ImageUitls;

import org.apache.commons.io.FilenameUtils;

import java.util.Map;

import all.com.jinyongqunxiax.model.mod.BattleManager;
import all.com.jinyongqunxiax.model.mod.DataManager;
import all.com.jinyongqunxiax.model.mod.GrowManager;
import all.com.jinyongqunxiax.model.mod.ItemManager;
import all.com.jinyongqunxiax.model.mod.MapManager;
import all.com.jinyongqunxiax.model.mod.MenpaiManager;
import all.com.jinyongqunxiax.model.mod.ResourceManager;
import all.com.jinyongqunxiax.model.mod.RoleManager;
import all.com.jinyongqunxiax.model.mod.ShopManager;
import all.com.jinyongqunxiax.model.mod.SkillAoyiManager;
import all.com.jinyongqunxiax.model.mod.SkillInternalManager;
import all.com.jinyongqunxiax.model.mod.SkillSpecialManager;
import all.com.jinyongqunxiax.model.mod.SkillsExternalManager;
import all.com.jinyongqunxiax.model.mod.StoryManager;
import all.com.jinyongqunxiax.model.mod.TaskManager;
import all.com.jinyongqunxiax.model.mod.TipManager;
import all.com.jinyongqunxiax.model.mod.TowerManager;
import all.com.jinyongqunxiax.model.mod.TriggerManager;
import jy.game.components.resource.JyResource;

public class Mod {
    private static final String DATA_PATH            = "index.xml";
    private static final String RESOURCE_PATH        = "Scripts/resource.xml";
    private static final String STORIES_PATH         = "Scripts/storys.xml";
    private static final String STORYSPY_PATH        = "Scripts/storysPY.xml";
    private static final String STORYSCG_PATH        = "Scripts/storysCG.xml";
    private static final String ROLES_PATH           = "Scripts/roles.xml";
    private static final String ITEMS_PATH           = "Scripts/items.xml";
    private static final String MAPS_PATH            = "Scripts/maps.xml";
    private static final String SKILLS_PATH          = "Scripts/skills.xml";
    private static final String INTERNAL_SKILLS_PATH = "Scripts/internal_skills.xml";
    private static final String SPECIAL_SKILLS_PATH  = "Scripts/special_skills.xml";
    private static final String AOYIS_PATH           = "Scripts/aoyis.xml";
    private static final String BATTLES_PATH         = "Scripts/battles.xml";
    private static final String TRIGGERS_GLOBAL_PATH = "Scripts/globaltrigger.xml";
    private static final String TRIGGERS_ITEM_PATH   = "Scripts/item_triggers.xml";
    private static final String GROW_TEMPLATES_PATH  = "Scripts/grow_templates.xml";
    private static final String MENPAI_PATH          = "Scripts/menpai.xml";
    private static final String TIPS_PATH            = "Scripts/resource_suggesttips.xml";
    private static final String ANIMATIONS_PATH      = "Scripts/animations.xml";
    private static final String SHOPS_PATH           = "Scripts/shops.xml";
    private static final String NEWBIE_PATH          = "Scripts/newbie.xml";
    private static final String TOWERS_PATH          = "Scripts/towers.xml";

    public DataManager           dataManager;
    public ResourceManager       resourceManager;
    public StoryManager          storyManager;
    public StoryManager          storyPYManager;
    public StoryManager          storyCGManager;
    public RoleManager           roleManager;
    public ItemManager           itemManager;
    public MapManager            mapManager;
    public SkillsExternalManager skillsExternalManager;
    public SkillInternalManager  skillInternalManager;
    public SkillSpecialManager   skillSpecialManager;
    public SkillAoyiManager      skillAoyiManager;
    public BattleManager         battleManager;
    public TriggerManager        triggerManager;
    public GrowManager           growManager;
    public MenpaiManager         menpaiManager;
    public TipManager            tipManager;
    public ShopManager           shopsManager;
    public TaskManager           taskManager;
    public TowerManager          towerManager;
    String root;

    Mod(String root) {
        this.root = root;
        dataManager = new DataManager(FilenameUtils.concat(root, DATA_PATH));
        resourceManager = new ResourceManager(FilenameUtils.concat(root, RESOURCE_PATH));

        storyManager = new StoryManager(FilenameUtils.concat(root, STORIES_PATH));
        storyPYManager = new StoryManager(FilenameUtils.concat(root, STORYSPY_PATH));
        storyCGManager = new StoryManager(FilenameUtils.concat(root, STORYSCG_PATH));

        roleManager = new RoleManager(FilenameUtils.concat(root, ROLES_PATH));
        itemManager = new ItemManager(FilenameUtils.concat(root, ITEMS_PATH));

        skillsExternalManager = new SkillsExternalManager(FilenameUtils.concat(root, SKILLS_PATH));
        skillInternalManager = new SkillInternalManager(FilenameUtils.concat(root, INTERNAL_SKILLS_PATH));
        skillSpecialManager = new SkillSpecialManager(FilenameUtils.concat(root, SPECIAL_SKILLS_PATH));
        skillAoyiManager = new SkillAoyiManager(FilenameUtils.concat(root, AOYIS_PATH));
        battleManager = new BattleManager(FilenameUtils.concat(root, BATTLES_PATH));
        mapManager = new MapManager(FilenameUtils.concat(root, MAPS_PATH));

        growManager = new GrowManager(FilenameUtils.concat(root, GROW_TEMPLATES_PATH));
        menpaiManager = new MenpaiManager(FilenameUtils.concat(root, MENPAI_PATH));
        shopsManager = new ShopManager(FilenameUtils.concat(root, SHOPS_PATH));
        taskManager = new TaskManager(FilenameUtils.concat(root, NEWBIE_PATH));
        tipManager = new TipManager(FilenameUtils.concat(root, TIPS_PATH));
        towerManager = new TowerManager(FilenameUtils.concat(root, TOWERS_PATH));
        triggerManager = new TriggerManager(FilenameUtils.concat(root, TRIGGERS_GLOBAL_PATH));
    }

    public enum Type {
        Animations, Audios, BattleBg, CGs, Heads,
        Icons, Items, lua, Maps, Scripts
    }

    public static ImageUitls.ImageSize suggestImageSize(String type) {
        float density = DrawUtils.density();
        switch (type) {
            case "items":
            case "Heads":
                return new ImageUitls.ImageSize(DrawUtils.dp2px(128), DrawUtils.dp2px(128));
            case "Icons":
                return new ImageUitls.ImageSize(DrawUtils.dp2px(128), DrawUtils.dp2px(128));
            case "BattleBg":
            case "Maps":
            case "CGs":
                return new ImageUitls.ImageSize(DrawUtils.dp2px(1140), DrawUtils.dp2px(640));
            default:
                return null;
        }
    }

    public static String requireName(String text) {
        switch (text) {
            case "daofa":
                return "刀法";
            case "jianfa":
                return "剑法";
            case "qimen":
                return "奇门";
            case "quanzhang":
                return "拳掌";

            case "wuxing":
                return "悟性";
            case "shenfa":
                return "身法";
            case "dingli":
                return "定力";
            case "bili":
                return "臂力";
            case "gengu":
                return "根骨";
            case "fuyuan":
                return "福源";
            case "talent":
                return "天赋";
            default:
                return text;
        }
    }

    public static String triggerName(String text) {
        switch (text) {
            case "AddHp":
                return "增加生命";
            case "AddMp":
                return "增加内力";
            case "RecoverHp":
                return "回复生命";
            case "RecoverMp":
                return "回复内力";
            case "AddBuff":
                return "";
            case "attack":
                return "攻击力,暴击率";
            case "defence":
                return "防御";
            case "critical":
                return "暴击";
            case "attribute":
                return "";
            case "powerup_skill":
                return "增强技能";
            case "anti_debuff":
                return "抵抗异常";
            case "sill":
                return "";
            case "internalskill":
                return "";
            default:
                return text;
        }
    }

    public static String typeName(String text) {
        switch (text) {
            case "BACKGROUND":
                return "背景";
            case "DIALOG":
                return "对话";
            case "LOG":
                return "日志";
            case "MUSIC":
                return "音乐";
            case "story":
                return "剧情";
            case "map":
                return "地图";
            case "BATTLE":
                return "战斗";
            case "JOIN":
                return "入队";
            case "JOIN_TEMP":
                return "入队(临时)";
            case "TEMP_JOIN":
                return "入队(临时)";
            case "SUGGEST":
                return "提示";
            case "ANIMATION":
                return "动画";
            case "AUDIOS":
                return "音频";
            case "CHANGE_FEMALE_NAME":
                return "CHANGE_FEMALE_NAME";
            case "CLEAR_FLAG":
                return "CLEAR_FLAG";
            case "CLEAR_LOG":
                return "CLEAR_LOG";
            case "COST_DAY":
                return "花费天数";
            case "COST_HOUR":
                return "花费时辰";
            case "COST_TIME":
                return "消耗时间";

            case "COST_ITEM":
                return "消耗物品";
            case "COST_MONEY":
                return "消耗银两";

            case "DAODE":
                return "DAODE";

            case "EFFECT":
                return "EFFECT";
            case "EXIT_MENPAI":
                return "退出门派";
            case "FOLLOW":
                return "追随";
            case "GET_MONEY":
                return "获取银两";
            case "GET_POINT":
                return "获得属性点数";
            case "GROWTEMPLATE":
                return "成长模板";
            case "HAOGAN":
                return "好感";
            case "HEAD":
                return "头像";
            case "HEAD_V2":
                return "头像V2";
            case "ITEM":
                return "获得物品";

            case "LEARN.INTERNALSKILL":
                return "学习内功";
            case "LEARN.SKILL":
                return "学习外功";
            case "LEARN.SPECIALSKILL":
                return "学习绝技";
            case "LEARN.TALENT":
                return "学习天赋";
            case "LEAVE":
                return "离队";
            case "LEAVE_ALL":
                return "所有人离队";
            case "LEAVE_FEMALES":
                return "女性离队";
            case "LEAVE_FOLLOW":
                return "LEAVE_FOLLOW";
            case "MAXLEVEL":
                return "武学上限";
            case "MENPAI":
                return "门派";
            case "MINUS_MAXPOINTS":
                return "减少最大点数";
            case "MONEY":
                return "银子";
            case "NEWBIE":
                return "新手任务";
            case "NICK":
                return "昵称";
            case "REMOVE.TALENT":
                return "移除天赋";
            case "SELECT":
                return "选择";
            case "SELECT_MENPAI":
                return "选择门派";
            case "SET_FLAG":
                return "SET_FLAG";
            case "SET_MAP":
                return "SET_MAP";
            case "SET_TIME_KEY":
                return "SET_TIME_KEY";
            case "SHAKE":
                return "晃动";
            case "SHOP":
                return "商店";

            case "TO_CHINESETIME":
                return "TO_CHINESETIME";
            case "UPGRADE.INTERNALSKILL":
                return "内功";
            case "UPGRADE.MAXHP":
                return "生命上限";
            case "UPGRADE.MAXMP":
                return "内力上限";
            case "UPGRADE.SKILL":
                return "外功";
            case "UPGRADE.刀法":
                return "刀法";
            case "UPGRADE.剑法":
                return "剑法";
            case "UPGRADE.奇门":
                return "奇门";
            case "UPGRADE.定力":
                return "定力";
            case "UPGRADE.悟性":
                return "悟性";
            case "UPGRADE.拳掌":
                return "拳掌";
            case "UPGRADE.根骨":
                return "根骨";
            case "UPGRADE.福源":
                return "福源";
            case "UPGRADE.福缘":
                return "福缘";
            case "UPGRADE.臂力":
                return "臂力";
            case "UPGRADE.身法":
                return "身法";
            case "YUANBAO":
                return "元宝";
            case "arena":
                return "arena";
            case "daode_less_than":
                return "道德<";
            case "daode_more_than":
                return "道德>";

            case "daofa_greater_than":
                return "刀法>";
            case "daofa_less_than":
                return "刀法<";

            case "jianfa_greater_than":
                return "剑法>";
            case "jianfa_less_than":
                return "剑法<";

            case "qimen_greater_than":
                return "奇门>";
            case "qimen_less_than":
                return "奇门<";
            case "quanzhang_greater_than":
                return "拳掌>";
            case "quanzhang_less_than":
                return "拳掌<";

            case "bili_greater_than":
                return "臂力>";
            case "dingli_greater_than":
                return "定力>";
            case "dingli_less_than":
                return "定力<";

            case "shenfa_greater_than":
                return "身法>";
            case "wuxing_greater_than":
                return "悟性>";
            case "wuxing_less_than":
                return "悟性<";
            case "gengu_greater_than":
                return "根骨>";
            case "haogan_less_than":
                return "好感<";
            case "haogan_more_than":
                return "好感>";

            case "skill_less_than":
                return "外功<";
            case "skill_more_than":
                return "外功>";

            case "exceed_day":
                return "exceed_day";
            case "friendCount":
                return "friendCount";
            case "game":
                return "game";
            case "gameFin":
                return "gameFin";
            case "gameOver":
                return "gameOver";
            case "game_mode":
                return "game_mode";
            case "have_item":
                return "拥有物品";
            case "have_money":
                return "拥有银两";
            case "have_not_item":
                return "have_not_item";
            case "have_yuanbao":
                return "拥有元宝";
            case "huashan":
                return "华山论剑";
            case "in_round":
                return "in_round";
            case "in_team":
                return "在队伍中";

            case "key_in_team":
                return "key_in_team";
            case "key_not_in_team":
                return "key_not_in_team";
            case "level_greater_than":
                return "等级>";
            case "mainmenu":
                return "mainmenu";
            case "maxhp_greater_than":
                return "生命上限 >";
            case "maxmp_greater_than":
                return "内力上限 >";
            case "nextZhoumu":
                return "下周目";

            case "not_has_time_key":
                return "not_has_time_key";
            case "not_have_item":
                return "没有物品";
            case "not_in_team":
                return "不在队伍";

            case "probability":
                return "概率";


            case "rank":
                return "等级";
            case "restart":
                return "restart";
            case "shop":
                return "商店";
            case "should_finish":
                return "完成任务";
            case "should_not_finish":
                return "未完成任务";

            case "tower":
                return "天关";
            case "trial":
                return "trial";
            case "tutorial":
                return "tutorial";

            case "xilian":
                return "洗练";
            case "zhenlongqiju":
                return "zhenlongqiju";
            case "zhoumu_greater_than":
                return "周目>";
            case "大地图":
                return "大地图";

            default:
                return text;
        }
    }

    public String load() {
        String result = "";
        try {
            validFiles();

            result += "\n" + battleManager.load();
            result += "\n" + growManager.load();
            result += "\n" + itemManager.load();
            result += "\n" + mapManager.load();
            result += "\n" + menpaiManager.load();
            result += "\n" + resourceManager.load();
            result += "\n" + roleManager.load();
            result += "\n" + shopsManager.load();

            result += "\n" + skillAoyiManager.load();
            result += "\n" + skillInternalManager.load();
            result += "\n" + skillsExternalManager.load();
            result += "\n" + skillSpecialManager.load();

            result += "\n" + storyManager.load();
            result += "\n" + storyPYManager.load();
            result += "\n" + storyCGManager.load();

            result += "\n" + taskManager.load();
            result += "\n" + tipManager.load();
            result += "\n" + towerManager.load();
            result += "\n" + triggerManager.load();

            result += "\n" + dataManager.load();

        } catch (Exception e) {
            result += "\n" + e.getMessage();
        }
        result = result.trim();
        return result;
    }

    private void validFiles() throws Exception {
//        String scriptPath = FilenameUtils.concat(root, "Scripts");
//        File[] files      = new File(scriptPath).listFiles((dir, name) -> FilenameUtils.getExtension(name).equals("xml"));
//
//        Context context = JxEditorApplication.shared.getApplicationContext();
//
//        for (File file : files) {
//            String fileName    = file.getName();
//            String xsdFileName = FilenameUtils.getBaseName(fileName) + ".xsd";
//            String xsdPath     = FilenameUtils.removeExtension(file.getPath()) + ".xsd";
//            File   xsdFile     = new File(xsdPath);
//            if (!xsdFile.exists()) {
//                // 使用内置的xsd
//                InputStream stream = null;
//                try {
//                    stream = context.getAssets().open(xsdFileName);
//                    FileUtils.copyToFile(stream, xsdFile);
//                } catch (Exception e) {
//                    // ret
//                }
//
//                JxFunc.of(stream).ifPresent(value -> {
//                    try {
//                        value.close();
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//                });
//            }
//
//            if (xsdFile.exists()) {
//                String validResult = XmlMFUtitls.validate(file.getPath(), xsdPath).trim();
//                if (!TextUtils.isEmpty(validResult)) {
//                    // 校验失败
//                    throw new Exception(validResult);
//                }
//            }
//        }
    }

    public void updateMD5(String component, String item) {
        dataManager.updateMD5(component, item, root);
    }

    public DataManager.Data data(String resourceKey) {
        JyResource resource = resourceManager.resourcesByKey.get(resourceKey);
        if (resource == null) {
            return null;
        }
        return dataManager.datas.get(resource.value);
    }

    public String imagePath(String resourceKey) {
        DataManager.Data data = data(resourceKey);
        if (data == null) {
            for (Map.Entry<String, DataManager.Data> entry : dataManager.datas.entrySet()) {
                if (entry.getKey().contains(resourceKey)) {
                    data = entry.getValue();
                }
            }
        }
        if (data != null) {
            return FilenameUtils.concat(root, data.fileName());
        }
        return "";
    }

    /**
     * ItemType 物品
     * 0 Costa //消耗品
     * 1 Weapon //武器
     * 2 Armor //防具
     * 3 Accessories = 3, //饰品
     * 4 Book = 4,  //武学书
     * 5 Mission //任务物品
     * 6 SpecialSkillBook = 6, //特殊技书
     * 7 TalentBook //天赋书
     * 8 Upgrade //升级材料
     * 9 Special //特殊物品
     * 10 CanZhang // 残章
     */

    /**
     * SkillCoverType 技能攻击范围
     * 0 NORMAL //点
     * 1 CROSS //十字
     * 2 STAR //星形
     * 3 LINE //直线
     * 4 FACE //面
     * 5 FAN  //扇形
     * 6 RING //环状
     * 7 x //对角线攻击
     * 8 FRONT //身前攻击
     */

    /**
     * JyCondition 条件语法
     * in_term 判定某队友必须在队中(参数 roleName)
     * not_in_term 判定某队友必须不在队中(参数 roleName) 判定某队友必须在队中(参数 roleKey)
     * key_in_term 判定某队友必须不在队中(参数 roleKey) 必须先完成剧情(参数 剧情名)
     * key_not_in_term 必须没有完成剧情(参数 剧情名) 必须有时间标志(参数 时间标志名)
     * has_time_key 必须没有时间标志(参数 时间标志名)
     * not_in_time 不在 XX 时辰(参数 时辰名，可多选，用“#”分隔)
     * in_time 在 XX 时辰(参数 时辰名，可多选，用“#”分隔)
     * have_money 必须有 XX 银子数(参数 银子数)
     * have_item 必须有 XX 物品(参数 物品名，或物品名#物品数量，如果不填物品数量，则默认 1 个)
     * game_mode 判定游戏模式(参数 难度值，三个难度值分别为 normal、hard、crazy)
     * exceed_day 判定游戏时间 XX 天以上(参数 天数)
     * not_exceed_day 判定游戏时间 XX 天以内(参数 天数)
     * in_menpai 判定是否属于某门派(参数 门派名)
     * not_in_menpai 判定是否不在某门派(参数 门派名)
     * has_menpai 判定角色是否有门派
     * in_round 判定当前是否是第 x 周目(参数 周目数)
     * not_in_round 判定当前是否不是第 x 周目(参数 周目数)
     * probability 一定概率，(参数 概率数 0-100)
     * daode_more_than 道德值大于等于多少(参数 道德值)
     * daode_lenss_than 道德值小于等于多少(参数 道德值)
     * haogan_more_than 女主角好感大于等于多少(参数 好感度)
     * haogan_less_then 女主角好感小于等于多少(参数 好感度)
     * skill_more_than 判定技能是否大于多少级(参数 roleKey#技能名#等级数)
     * skill_less_than 判定技能是否小于多少级
     * level_greater_than 判定某个角色是否多少等级以上(参数 roleKey#等级数)
     * dingli_greater_than 判定某个角色定力是否多少以上(参数 roleKey#定力数)
     * wuxing_greater_than 同上，悟性
     * dingli_less_than 同上，定于小于
     * wuxing_less_than 同上，悟性小于
     * friendCount 判定队友数量是否大于等于多少，(参数 数量)
     */


    /**
     * 武学
     */
    static class WuXue {
        static String attributeToChinese(String attribute) {
            switch (attribute) {
                case "costball":
                    return "消耗怒气";
                case "castsize":
                    return "施展范围";
                case "coversize":
                    return "覆盖范围";
                case "covertype":
                    return "覆盖类型";
                case "requirelv":
                    return "等级要求";
                default:
                    return attribute;
            }
        }
    }
}